﻿#region Using Directives

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;

    using Csla;

    using MarketPulse.BusinessLogic.Core;

#endregion

namespace MarketPulse.BusinessLogic.Common
{
    /// <summary>
    /// This class represents a read only instance of a user within the system. Users can be of different types, so this user info CAN represent a shopper, auditor, system user or exit interviewer etc...
    /// </summary>
    [Serializable]
    [Csla.Server.ObjectFactory("MarketPulse.DataAccess.Factory.UserFactory, MarketPulse.DataAccess.Factory", "FetchInfo")]
    public class UserInfo : MarketPulseReadOnlyBase<UserInfo>
    {
        #region Member Variables

            /// <summary>
            /// The username for this User
            /// </summary>
            public static PropertyInfo<string> mUsernameProperty = RegisterProperty<string>(p => p.Username);

            /// <summary>
            /// The password for this User
            /// </summary>
            public static PropertyInfo<string> mPasswordProperty = RegisterProperty<string>(p => p.Password);

            /// <summary>
            /// The fullname for this User
            /// </summary>
            public static PropertyInfo<string> mFullNameProperty = RegisterProperty<string>(p => p.FullName);

            /// <summary>
            /// The first name for this User
            /// </summary>
            public static PropertyInfo<string> mFirstnameProperty = RegisterProperty<string>(p => p.Firstname);

            /// <summary>
            /// The last name for this User
            /// </summary>
            public static PropertyInfo<string> mLastNameProperty = RegisterProperty<string>(p => p.Lastname);

            /// <summary>
            /// The email address for this User
            /// </summary>
            public static PropertyInfo<string> mEMailProperty = RegisterProperty<string>(p => p.EMail);

            /// <summary>
            /// The number of failed login attempts for this User
            /// </summary>
            public static PropertyInfo<long> mFailedLogonAttemptsProperty = RegisterProperty<long>(p => p.FailedLogonAttempts);

            #region Association Member Variables (Related Objects)

                //TODO Refactor to use an AssignentInfoList
                /// <summary>
                /// A list of the Users visits
                /// </summary>
                public static PropertyInfo<VisitInfoList> mVisitInfoListProperty = RegisterProperty<VisitInfoList>(p => p.VisitInfoList);

            #endregion

        #endregion

            #region Constructors

            /// <summary>
            /// Default constructor is private in order to (try to) enforce construction
            /// only via the static factory methods provided.
            /// </summary>
            private UserInfo()
            {
            }

        #endregion

        #region Methods

            #region Factory Methods

                /// <summary>
                /// Method used to retrieve a User an info object 
                /// </summary>
                /// <param name="guid">The guid of the User info object to retrieve</param>
                /// <returns>The populated User info object survey</returns>
                public static UserInfo Get(Guid guid)
                {
                    return DataPortal.Fetch<UserInfo>(new SingleCriteria<Guid>(guid));
                }

                /// <summary>
                /// Method used to retrieve a User an info object 
                /// </summary>
                /// <param name="guid">The guid of the User info object to retrieve</param>
                /// <returns>The populated User info object survey</returns>
                public static UserInfo GetByGuid(Guid guid)
                {
                    return DataPortal.Fetch<UserInfo>(new SingleCriteria<Guid>(guid));
                }

                /// <summary>
                /// Method used to retrieve a User an info object by username
                /// </summary>
                /// <param name="username">The username of the User info object to retrieve</param>
                /// <returns>The populated User info object survey</returns>
                public static UserInfo GetByUsername(string username)
                {
                    return DataPortal.Fetch<UserInfo>(new SingleCriteria<string>(username));
                }

            #endregion  
        
            /// <summary>
            /// (Overridden) method used to provide a string based representation of the object. In this case the full name of the User
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                StringBuilder fullName = new StringBuilder();
                fullName.Append(Firstname);
                fullName.Append(" ");
                fullName.Append(Lastname);
                return fullName.ToString();
            }

        #endregion

        #region Properties

            /// <summary>
            /// The username for this User
            /// </summary>
            public string Username { get { return GetProperty(mUsernameProperty); } }

            /// <summary>
            /// The password for this User
            /// </summary>
            public string Password { get { return GetProperty(mPasswordProperty); } }

            /// <summary>
            /// The fullname for this User
            /// </summary>
            public string FullName { get { return GetProperty(mFullNameProperty); } }

            /// <summary>
            /// The first name for this user
            /// </summary>
            public string Firstname { get { return GetProperty(mFirstnameProperty); } }

            /// <summary>
            /// The last name for this user
            /// </summary>
            public string Lastname { get { return GetProperty(mLastNameProperty); } }

            /// <summary>
            /// The email address for the user
            /// </summary>
            public string EMail { get { return GetProperty(mEMailProperty); } }

            /// <summary>
            /// A numeric value representing the number of failed login attempts for a user
            /// </summary>
            public long FailedLogonAttempts { get { return GetProperty(mFailedLogonAttemptsProperty); } }

            #region Association Properties (Related Objects)

                /// <summary>
                /// A list of the users visits
                /// </summary>
                public VisitInfoList VisitInfoList
                {
                    get
                    {
                        if (!FieldManager.FieldExists(mVisitInfoListProperty))
                        {
                            LoadProperty(mVisitInfoListProperty, VisitInfoList.GetByUserGUID(this.GUID.Value));
                            OnPropertyChanged(mVisitInfoListProperty);
                        }
                        return ReadProperty(mVisitInfoListProperty);
                    }
                }

            #endregion

        #endregion       

    }
}
